package com.opesoft.fw.mvc;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;

import com.opesoft.fw.core.Constants;
import com.opesoft.fw.core.utils.StrUtils;

public class ControllerServlet extends HttpServlet
{
	Logger log=Logger.getLogger(this.getClass());

	ServletConfig cfg;
	static public String mode;
	// static public String packageRoot; // 存放Controller类的包的位置
	static Map<String, String> mapping=new HashMap<String, String>(); // 用于存放Path->Package的映射关系

	public void init(ServletConfig servletConfig) throws ServletException
	{
		// 初始化系统运行的模式
		cfg=servletConfig;

		// 如果没有初始化系统的Mode，就进行初始化
		if(ControllerServlet.mode==null)
		{
			mode=cfg.getInitParameter("mode");

			// 检查是否是已知模式
			if(!("develop".equalsIgnoreCase(mode)||"product".equalsIgnoreCase(mode))) log.error("System's mode must is one of 'develop' or 'product' !");
			else Constants.MODE=mode;

			log.info("Format system's mode is ["+Constants.MODE+"] .");
		}

		// 初始化Path->Package的映射关系
		{
			String s1=cfg.getInitParameter("mapping");
			if(s1!=null&&s1.length()>0)
			{
				String[] a1=s1.split(",");
				for(String s2 : a1)
				{
					String[] a2=s2.split("=");
					if(a2.length>1)
					{
						ControllerServlet.mapping.put(a2[0],a2[1]);
						log.debug("Init controlelr mapping : "+a2[0]+" -> "+a2[1]);
					}
				}
			}
		}

		super.init(servletConfig);

		Constants.WEB_ROOT=this.getServletContext().getRealPath("/");
		log.debug("Init constant parameter WEB_ROOT : "+Constants.WEB_ROOT);
	}

	protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException
	{
		String actionClass=ControllerServlet.mappingClassPath(request.getRequestURI(),request.getContextPath());

		try
		{
			View result;
			Action action=(Action)Class.forName(actionClass).newInstance();
			try
			{
				action.init(request,response);
				action.before();
				result=action.execute();
				action.after();
			}
			catch(Exception e)
			{
				result=action.error(e); // Action用于处理异常的接口
			}

			// 处理返回值
			if(result!=null)
			{
				if(result.getType()==View.PAGE_TYPE) request.getRequestDispatcher((String)result.getData()).forward(request,response);
				else log.error("Can't dispose Action's result : "+result);
			}
		}
		catch(Exception e)
		{
			log.error(e);
			if(Constants.MODE.equalsIgnoreCase("develop")) e.printStackTrace();
		}
	}

	protected void doPost(HttpServletRequest arg0,HttpServletResponse arg1) throws ServletException,IOException
	{
		this.doGet(arg0,arg1);
	}

	/*
	 * 把URI转换成对应的Class
	 */
	static public String mappingClassPath(String uri,String contextPath)
	{
		if(uri.indexOf(".")>-1) uri=uri.split("[.]")[0];
		if(contextPath!=null&&contextPath.length()>0) uri=uri.substring(contextPath.length(),uri.length());

		if(uri.startsWith("/")) uri=uri.substring(1);
		String mapping=ControllerServlet.mapping.get(uri.substring(0,uri.indexOf("/")));
		if(mapping==null) return StrUtils.uri2class(uri);
		else
		{
			if(!mapping.endsWith(".")) mapping+=".";
			return mapping+StrUtils.uri2class(uri.substring(uri.indexOf("/")));
		}
	}

}
